home *** CD-ROM | disk | FTP | other *** search
/ HaCKeRz Kr0nlcKLeZ 1 / HaCKeRz Kr0nlcKLeZ.iso / chibacity / gbbdisk.arj / CAROMAG / HEADER2.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1994-01-25  |  11.6 KB  |  296 lines

  1. program investigate_header;  {Investigate a Windows 3.1 EXE header}
  2. uses crt;
  3.  
  4. type
  5.   OLD_HEADER_TYPE        =record
  6.     ID_Word              :word;    {Better be MZ}
  7.     Last_Page_Size       :word;    {Size of last page}
  8.     Page_Count           :word;    {512 byte blocks}
  9.     Rel_Table_Entries    :word;    {Entries in relocation table}
  10.     Header_Size          :word;    {16 byte paragraphs}
  11.     MINALLOC             :word;    {Min size program needs, 16 byte paragraphs}
  12.     MAXALLOC             :word;    {Max size program will take, 16 byte paragraphs}
  13.     Init_SS              :word;    {Initial stack (relocated)}
  14.     Init_SP              :word;
  15.     Checksum             :word;    {Normally not used}
  16.     Init_IP              :word;    {Entry point (relocated)}
  17.     Init_CS              :word;
  18.     Reloc_Table_Offset   :word;    {Location of relocation table, from start of file}
  19.                                    {If >=40H, then value at 3CH is offset to new style header}
  20.     Overlay_No           :word;    {Overlay number, 0 for programs}
  21.     Filler               :array[$1C..$3B] of byte;
  22.     New_Header_Offset    :word;
  23.     end;
  24.  
  25.   NEW_HEADER_TYPE        =record
  26.     Signature            :word;    {00 Better be NE}
  27.     Linker_Version       :byte;    {02 Self-explanatory}
  28.     Linker_Revision      :byte;    {03}
  29.     Entry_Table_Offset   :word;    {04}
  30.     Entry_Table_Length   :word;    {06}
  31.     Reserved1a           :word;    {08}
  32.     Reserved1b           :word;    {0A}
  33.     Flags                :word;    {0C}
  34.     Automatic_Data_Seg   :word;    {0E 0 if SINGLEDATA and MULTIPLEDATA not specified}
  35.     Local_Heap_Size      :word;    {10 Initial local heap size in bytes}
  36.     Stack_Size           :word;    {12 Initial stack size, in bytes}
  37.     Init_IP              :word;    {14 Initial entry point}
  38.     Init_CS              :word;    {16 Index to segment table!'}
  39.     Init_SP              :word;    {18 Initial stack}
  40.     Init_SS              :word;    {1A}
  41.     Segment_Table_Entries:word;    {1C Number of entries in segment table}
  42.     Mod_Ref_Table_Entries:word;    {1E Number of entries in module reference table}
  43.     Non_NameTable_Entries:word;    {20 Number of entries in non-resident name table}
  44.     Seg_Table_Offset     :word;    {22 Offset to segment table, from start of new header}
  45.     Resrc_Table_Offset   :word;    {24 Offset to resource table}
  46.     Res_Name_Table_Offset:word;    {26 Offset to resident name table}
  47.     Mod_Ref_Table_Offset :word;    {28 Offset to module reference table}
  48.     Imp_Name_Table_Offset:word;    {2A Offset to imported names table}
  49.     Nrs_Name_Table_Offset:longint; {2C Offset to non-resident name table, from BEGINNING of file in bytes}
  50.     Moveable_Entry_Pts   :word;    {30 Number of moveable entry points}
  51.     Seg_Alignment        :word;    {32 Log base 2 of segment sector size, defailt=9-->512 bytes}
  52.     Resource_Segments    :word;    {34 Specifies number of resource segments}
  53.     Op_system            :byte;    {36 Flags indicate what operating system this file is for 0=unknown, 1=OS/2, 2=Windows}
  54.     Flags2               :byte;    {37}
  55.     Fast_Load_Start      :word;    {38 Specifies start of fast load area}
  56.     Fast_Load_End        :word;    {3A End of fast load area}
  57.     Reserved2            :word;    {3C}
  58.     Win_Version          :word;    {3E Specifies windows version number}
  59.     end;
  60.  
  61.   SEG_TABLE_TYPE         =record
  62.     Offset               :word;
  63.     Size                 :word;
  64.     Attributes           :word;
  65.     Alloc                :word;
  66.     end;
  67.  
  68.   RES_INFO_TYPE          =record
  69.     ResType              :word;
  70.     Count                :word;
  71.     Reserved             :longint;
  72.     end;
  73.  
  74.   RES_NAME_INFO_TYPE     =record
  75.     Offset               :word;
  76.     Length               :word;
  77.     Flags                :word;
  78.     ID                   :word;
  79.     Handle               :word;
  80.     Usage                :word;
  81.     end;
  82.  
  83.   ENTRY_MOVEABLE_TYPE    =record
  84.     Flags                :byte;
  85.     INT_3F               :word;
  86.     Segment              :byte;
  87.     Offset               :word;
  88.     end;
  89.  
  90.   ENTRY_FIXED_TYPE       =record
  91.     Flags                :byte;
  92.     Offset               :word;
  93.     end;
  94.  
  95.   REL_INFO_TYPE          =record
  96.     rela_type            :byte;
  97.     rel_type             :byte;
  98.     rofs                 :word;
  99.     r1                   :word;
  100.     r2                   :word;
  101.     end;
  102.  
  103. var
  104.   f                :file;
  105.   fname            :string;
  106.   fo               :text;
  107.   foname           :string;
  108.   old_header       :OLD_HEADER_TYPE;
  109.   new_header       :NEW_HEADER_TYPE;
  110.   seg_table        :SEG_TABLE_TYPE;
  111.   i,j,k            :word;
  112.   module_name      :string;
  113.   resident_name    :string;
  114.   res_info         :RES_INFO_TYPE;
  115.   res_name_info    :RES_NAME_INFO_TYPE;
  116.   resource_name    :string;
  117.   seg_align        :longint;
  118.   res_align        :longint;
  119.   Entry_Moveable   :ENTRY_MOVEABLE_TYPE;
  120.   Entry_Fixed      :ENTRY_FIXED_TYPE;
  121.   cs_size          :word;
  122.   cs_loc           :longint;
  123.   rel_count        :word;
  124.   rel_info         :REL_INFO_TYPE;
  125.   IMName           :array[1..20] of string;
  126.  
  127. function hex(w:word):string;
  128. const h:array[0..15] of char=('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
  129. begin
  130.   hex:=h[w div 4096] + h[(w div 256) and 15] + h[(w div 16) and 15] + h[w and 15];
  131. end;
  132.  
  133. function imported_name(j:word):string;
  134. var
  135.   s                :string;
  136.   n,i              :word;
  137. begin
  138.   n:=1;
  139.   for i:=1 to j do
  140.     begin
  141.       seek(f,old_header.New_Header_Offset+new_header.Imp_Name_Table_Offset+n);
  142.       blockread(f,s,255);
  143.       if ord(s[0])>0 then n:=n+ord(s[0])+1;
  144.     end;
  145.   imported_name:=s;
  146. end;
  147.  
  148. begin
  149.   fname:=ParamStr(1);
  150.   if ParamCount<>2 then AssignCRT(fo) else
  151.     begin
  152.       foname:=ParamStr(2);
  153.       assign(fo,foname);
  154.     end;
  155.   rewrite(fo);
  156.   assign(f,fname);
  157.   reset(f,1);                   {open with 1 byte block}
  158.   blockread(f,old_header,sizeof(old_header));
  159.   if ParamCount<>2 then ClrScr;
  160.   if old_header.ID_Word<>ord('M')+256*ord('Z') then
  161.     begin
  162.       writeln(fo,'This is not an EXE file!!');
  163.       halt;
  164.     end;
  165.   if old_header.Reloc_Table_Offset>=$40 then
  166.     begin
  167.       seek(f,old_header.New_Header_Offset);
  168.       blockread(f,new_header,sizeof(new_header));
  169.       if ParamCount<>2 then clrscr;
  170.       with new_header do    {Display header info}
  171.         begin
  172.           writeln(fo,'Initial CS:IP =                  #',Init_CS,':',hex(Init_IP),'H');
  173.           writeln(fo,'Initial SS:SP =                  #',Init_SS,':',hex(Init_SP),'H Size = ',Stack_Size);
  174.           writeln(fo,'Segment table entries =          ',Segment_Table_Entries);
  175.           writeln(fo,'Module reference table entries = ',Mod_Ref_Table_Entries);
  176.           writeln(fo,'Moveable entry points =          ',Moveable_Entry_Pts);
  177.           writeln(fo,'Resource segments =              ',Resource_Segments);
  178.           writeln(fo,'Automatic data segment =         ',Automatic_Data_Seg);
  179.           writeln(fo,'Fast load offset =               ',Fast_Load_Start);
  180.         end;
  181.       writeln(fo);
  182.       writeln(fo,'Modules referenced: ');
  183.       for i:=1 to new_header.Mod_Ref_Table_Entries do
  184.         begin
  185.           seek(f,old_header.New_Header_Offset+new_header.Mod_Ref_Table_Offset+2*(i-1));
  186.           blockread(f,j,2);
  187.           seek(f,old_header.New_Header_Offset+new_header.Imp_Name_Table_Offset+j);
  188.           blockread(f,module_name,256);
  189.           writeln(fo,'   ',i,': ',module_name);
  190.           IMName[i]:=module_name;
  191.         end;
  192.       writeln(fo);
  193.       write(fo,'Resident names: ');
  194.       j:=0;
  195.       repeat
  196.         seek(f,old_header.New_Header_Offset+new_header.Res_Name_Table_Offset+j);
  197.         blockread(f,resident_name,256);
  198.         j:=j+ord(resident_name[0])+2;
  199.         write(fo,resident_name,' ');
  200.       until resident_name[0]=#0;
  201.       writeln(fo);
  202.       writeln(fo,'Non-resident names: ');
  203.       j:=0;
  204.       repeat
  205.         seek(f,new_header.NRS_Name_Table_Offset+j);
  206.         blockread(f,resident_name,256);
  207.         j:=j+ord(resident_name[0])+3;
  208.         k:=ord(resident_name[ord(resident_name[0])+1])
  209.             +256*ord(resident_name[ord(resident_name[0])+2]);
  210.         writeln(fo,k:5,'  ',resident_name);
  211.       until resident_name[0]=#0;
  212.       writeln(fo);
  213.       seg_align:=1;
  214.       if new_header.Seg_Alignment<>0 then for i:=1 to new_header.Seg_Alignment do seg_align:=2*seg_align
  215.       else seg_align:=512;
  216.       writeln(fo,'Segments: (Alignment=',seg_align,'(',new_header.Seg_Alignment,'))');
  217.       writeln(fo,'Offset   Length   Alloc Size   Attributes');
  218.       for i:=1 to new_header.Segment_Table_Entries do
  219.         begin
  220.           seek(f,old_header.New_Header_Offset+new_header.Seg_Table_Offset+8*(i-1));
  221.           blockread(f,seg_table,sizeof(seg_table));
  222.           write(fo,seg_table.offset:5,seg_table.size:9,seg_table.alloc:13,'    ');
  223.           if seg_table.attributes and 1 = 1 then write(fo,'DATA ') else write(fo,'CODE ');
  224.           if seg_table.attributes and 2 = 2 then write(fo,'Allocated ');
  225.           if seg_table.attributes and 4 = 4 then write(fo,'Loaded ');
  226.           if seg_table.attributes and 16 = 16 then write(fo,'Moveable ') else write(fo,'Fixed ');
  227.           if seg_table.attributes and 32 = 32 then write(fo,'Shareable ');
  228.           if seg_table.attributes and 64 = 64 then write(fo,'Preload ');
  229.           if seg_table.attributes and 128 = 128 then write(fo,'Exec_Only/Read_Only ');
  230.           if seg_table.attributes and 256 = 256 then write(fo,'Contains_Rel_Data ');
  231.           if seg_table.attributes and 4096 = 4096 then write(fo,'Discardable ');
  232.           writeln(fo);
  233.           if i=New_Header.Init_CS then
  234.             begin
  235.               cs_size:=seg_table.size;
  236.               cs_loc:=seg_table.offset*seg_align;
  237.             end;
  238.         end;
  239.       writeln(fo);
  240.       writeln(fo,'Entry table:');
  241.       seek(f,old_header.New_Header_Offset+new_header.Entry_Table_Offset);
  242.       repeat
  243.         blockread(f,j,2);
  244.         if j shr 8 = $FF then
  245.           begin
  246.             writeln(fo,'Moveable:');
  247.             for i:=1 to j and $FF do
  248.               begin
  249.                 blockread(f,Entry_Moveable,sizeof(Entry_Moveable));
  250.                 writeln(fo,Entry_Moveable.Segment,':',hex(Entry_Moveable.Offset));
  251.               end;
  252.           end;
  253.         if j shr 8 = $FE then
  254.           begin
  255.             writeln(fo,'Constant:');
  256.           end;
  257.         if not (j shr 8 in [0,$FE,$FF]) then
  258.           begin
  259.             writeln(fo,'Fixed: (',j and $FF,')');
  260.             for i:=1 to j and $FF do
  261.               begin
  262.                 blockread(f,Entry_Fixed,sizeof(Entry_Fixed));
  263.                 writeln(fo,j shr 8,':',hex(Entry_Fixed.Offset));
  264.               end;
  265.           end;
  266.       until (j and $FF) = 0;
  267.       writeln(fo);
  268.       writeln(fo,'Relocation data: ');
  269.       seek(f,cs_loc+cs_size);
  270.       blockread(f,rel_count,2);
  271.       for i:=1 to rel_count do
  272.         begin
  273.           blockread(f,rel_info,sizeof(rel_info));
  274.           write(fo,rel_info.rela_type:3,'  ',rel_info.rofs:5,'  ');
  275.           case rel_info.rel_type of
  276.             0 : write(fo,'Internal Ref    ');
  277.             1 : begin
  278.                   write(fo,'Imported ord    ');
  279.                   write(fo,IMName[rel_info.r1],'.',rel_info.r2);
  280.                 end;
  281.             2 : write(fo,'Imported Name   ');
  282.             3 : write(fo,'OS FIXUP        ');
  283.             else write(fo,'UNKNOWN REL TYP');
  284.             end;
  285.           writeln(fo);
  286.         end;
  287.     end
  288.   else writeln(fo,'This is a standard DOS EXE file.');
  289.  
  290.   writeln(fo);
  291.   writeln(fo,'Press any key to continue.');
  292.   if ParamCount<>2 then if ReadKey=' ' then ;
  293.   close(fo);
  294.   close(f);
  295. end.
  296.